// geo-calculations ref: http://www.movable-type.co.uk/scripts/latlong.html

var MODE_MANUAL = 1;
var MODE_AUTO = 2;
var MODE_LIVEGPS = 3;

var simulatorMode = MODE_MANUAL;

var map;				// the main Google map element
var directionsService;	// google maps directions service 
var directionsDisplay;  // directions renderer
var dest_markers = []; 	// an array of destination markers
var man_marker;			// the robot marker

var NY = new google.maps.LatLng(40.6395, -73.9613);

var broadcastON = false;
var bcastInterval = null; // not a number, a timer object...

var simulationON = false;
var simulator;
var simulOptions;

function isManualMode(){ return simulatorMode == MODE_MANUAL; }
function isAutoMode(){ return simulatorMode == MODE_AUTO; }
function isLiveGPSMode(){ return simulatorMode == MODE_LIVEGPS; }


function setSimulMode(new_mode){

//	if (simulatorMode == new_mode) 
//		return;
	
	simulatorMode = new_mode;
	
	// enable / disable controls
	man_marker.setDraggable(isManualMode());
	
	for (var i = 0; i < dest_markers.length; i++) 
		dest_markers[i].setVisible(isAutoMode());
	
	if (isAutoMode()) {
	    $('#info_bar').removeClass('hidden');
		$('.imgBtn').removeClass('disabledIcon');
		update_route();
	}
	else {
	    $('#info_bar').addClass('hidden');
		$('.imgBtn').addClass('disabledIcon');
		if(directionsDisplay)
			directionsDisplay.setMap(null); // remove directions
		directionsDisplay = null;
	}
}

function bcast_timerElapsed(a, b) {
	
	// show 'broadcasting'
	$('#bcast_enable_btn').addClass('bcastingNow');
	$('#satDishIcon').removeClass('hidden');

	// broadcast man marker position
	manPos = man_marker.getPosition();
	broadcast_location(manPos.lat(), manPos.lng(), simulator.currSpeed);
	// alert("speed is " + simulator.currSpeed);
	
	// hide 'broadcasting'
	setTimeout("$('#satDishIcon').addClass('hidden'); $('#bcast_enable_btn').removeClass('bcastingNow');", 2000);
	
}

function livegps_timerElapsed(a, b) {
	// sample gps
	// re-position man marker
	// center map on man
}

function create_man_marker() {
	
	// dimensions, origin, anchor
	var manImg = new google.maps.MarkerImage("./img/markers/man.png",
		new google.maps.Size(32, 32),
		new google.maps.Point(0,0),
		new google.maps.Point(16,32));

	var shadowImg = new google.maps.MarkerImage("./img/markers/man.shadow.png",
		new google.maps.Size(59, 32),
		new google.maps.Point(0,0),
		new google.maps.Point(15, 32));

	
	man_marker = new google.maps.Marker({
		position: NY, 
		map: map,
		title: "Robot",
		icon: manImg,
		shadow: shadowImg,
		draggable: isManualMode(),
	});
	
	// Update tooltip with coordinates automatically
	google.maps.event.addListener(man_marker, 'position_changed', function() {
		man_marker.setTitle('Robot at ' + man_marker.getPosition().toString());
	});
}


function update_route(){

	if (dest_markers == null || dest_markers.length == 0) {
		return;
	}
	
	if (directionsDisplay == null) {
		
		directionsDisplay = new google.maps.DirectionsRenderer({
			map: map,
			preserveViewport: true,
			suppressInfoWindows: true,
			suppressMarkers: true
		});
	}
	waypoints = [];
	for(var i=0; i < dest_markers.length-1; i++) // all excluding final dest
		waypoints.push({
          location: dest_markers[i].getPosition(),
          stopover: false
      });
	
	start = man_marker.getPosition();
	end = dest_markers[dest_markers.length-1].getPosition();
	
	var request = {
        origin: start,
		waypoints: waypoints,
        destination: end,
        travelMode: google.maps.DirectionsTravelMode.DRIVING,
		unitSystem: google.maps.DirectionsUnitSystem.METRIC
		
    };
    directionsService.route(request, function(result, status){
        if (status == google.maps.DirectionsStatus.OK) {
            directionsDisplay.setDirections(result);
			simulOptions.directions = result;
        }
    });
}

function map_OnClick_handler(event){

	if(!isAutoMode() || simulationON) // not in automatic mode OR during simulation
		return;

	if (dest_markers.length == 26) {
		alert("Too many destinations (max = 26). Clear the map.");
		return;
	}

	// Marker sizes are expressed as a Size of X,Y
	// where the origin of the image (0,0) is located
	// in the top left of the image.

	// dimensions, origin, anchor
	markerXimg = new google.maps.MarkerImage("./img/markers/darkgreen_Marker" + (dest_markers.length+1) + ".png",
		new google.maps.Size(20, 34),
		new google.maps.Point(0,0),
		new google.maps.Point(10,34));
	
	shadowImg = new google.maps.MarkerImage("./img/markers/marker.shadow.png",
		new google.maps.Size(59, 32),
		new google.maps.Point(0,0),
		new google.maps.Point(15, 32));

	new_dest_marker = new google.maps.Marker({
		position: event.latLng, 
		map: map,
		title: "Destination " + (dest_markers.length+1),
		icon: markerXimg,
		shadow: shadowImg,
		draggable: true
	});

	dest_markers.push(new_dest_marker);
	
	update_route(); // recalculate route
	
	// Update route on destination change automatically
	google.maps.event.addListener(new_dest_marker, 'dragend', function() {
		update_route();
	});
}

function simul_step_callback (total_distance, current_speed) {
	$('#distanceInfo').html((total_distance/1000.0).toFixed(2) + " Km");
	$('#speedInfo').html((current_speed * 3.6).toFixed(1) + " Km/Hr");
}

function initialize() {
	
	//window.resizeTo(1000, 600);
	
	$('#followBtn').click(function() {
  		map.setCenter(man_marker.getPosition());
	});
	
	$('#createRoadBtn').click(function() {
  		var name = prompt("Name this new road", "Road 1");
        
        if (name == null)
            return;
        
        req_add_road(name, directionsDisplay.getDirections());
	});
	
	$('#newSimulBtn').click(function() {
  		for (var i = 0; i < dest_markers.length; i++)
			dest_markers[i].setMap(null);
		
		dest_markers = []; // clear markers
		
		update_route();
		
		if(simulator != null)
			simulator.restart();
	});
		
	$('#runSimuBtn').click(function() {
  		set_simulation_enabled(!simulationON);
	});
	
		
	map = new google.maps.Map($("#map_canvas")[0], {
		zoom: 13,
		center: NY,
		mapTypeId: google.maps.MapTypeId.ROADMAP,
		disableDefaultUI: true,
		scaleControl: true
	});

	directionsService = new google.maps.DirectionsService();

	$('#simul_mod').change(function () {
		setSimulMode(parseInt($("#simul_mod").val()));
	});
	
	$('#bcast_interval').change(function () {
		update_bcast_timer();
	});

	$('#simul_speed').change(function () {
		simulOptions.speed = $('#simul_speed').val();
	});

	$('#bcast_enable_btn').click(function () {
		
		broadcastON = !broadcastON;
		update_bcast_timer();
		
		// toggle red/green colors
		if (bcast_is_triggered())
		    bcast_timerElapsed('','');
		else
		    $('#bcast_enable_btn').toggleClass('bcastOn bcastOff').html(broadcastON ? 'Online' : 'Offline');
	});

	// add info bar
	infoBar = $('#info_bar').remove().removeClass('hidden')[0];
	infoBar.index = 1;
  	map.controls[google.maps.ControlPosition.BOTTOM].push(infoBar);
	
	create_man_marker();
	

	google.maps.event.addListener(map, 'click', map_OnClick_handler);
	
	setSimulMode(MODE_MANUAL);

	simulOptions = {
		map: map,
		marker: man_marker,
		tick: 1000,
		trackMarker: true,
		endcallback: null,
		stepcallback: simul_step_callback,
		speed: 'legal',
		loop: false
	};

	simulator = new MarkerSimulator(simulOptions);
}

function bcast_is_triggered() {
    var val = $('#bcast_interval').val();
    
    return val == "triggered";
}

function update_bcast_timer() {
	
	// first disable current timer if one is working
	if(bcastInterval != null){
		clearInterval(bcastInterval); // disable timer
		bcastInterval = null;
	}
	    
    if (bcast_is_triggered()) // no timer
        return;
	
	// now init/re-init timer with updated values, if broadcasting is ON
	if (broadcastON){
		interval = parseInt($('#bcast_interval').val()) * 1000;  // seconds * 1000 msecs
		bcastInterval = window.setInterval(bcast_timerElapsed, interval);
	}
}



function set_simulation_enabled(isEnabled) {
	
	if(isEnabled == simulationON || !isAutoMode())
		return; // nothing to do
	
	simulationON = isEnabled;
	$('#runSimuBtn').toggleClass('runIcon pauseIcon').html(simulationON ? 'Pause' : "Run");
	
	if (isEnabled)
		simulator.run();
	else 
		simulator.pause();
}

// main
$(document).ready(initialize);
